package biz.datalk.industrialland.admin.modules.online.dynform.service.impl;

import biz.datalk.industrialland.admin.modules.common.servie.ICommonService;
import biz.datalk.industrialland.admin.modules.online.config.cfg.DynformConstant;
import biz.datalk.industrialland.admin.modules.online.dynform.mapper.IDynformHeadMapper;
import biz.datalk.industrialland.admin.modules.online.dynform.pojo.dto.DynformFieldDTO;
import biz.datalk.industrialland.admin.modules.online.dynform.pojo.po.DynformHead;
import biz.datalk.industrialland.admin.modules.online.dynform.pojo.po.DynformHeadExample;
import biz.datalk.industrialland.admin.modules.online.dynform.service.IDynformAutoService;
import biz.datalk.industrialland.admin.modules.online.dynform.service.IDynformCacheService;
import biz.datalk.industrialland.admin.modules.online.dynform.service.IDynformServices;
import biz.datalk.industrialland.common.util.RedisUtil;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

/**
 *
 *
 * @author tarofang@163.com
 * @date 2020-04-08
 *
 */
@Slf4j
@Service
public class DynformCacheServiceImpl implements IDynformCacheService {

    @Autowired
    private IDynformServices dynformServices;

    @Autowired
    private ICommonService commonService;

    @Value(value = "${core.file.view-prefix}")
    private String previewPrefix;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private IDynformHeadMapper dynformHeadMapper;

    @Autowired
    private IDynformAutoService dynformAutoService;

    @Override
    public void refresh() {
        DynformHeadExample example = new DynformHeadExample();
        List<DynformHead> dynformHeads = dynformHeadMapper.selectByExample(example);
        dynformHeads = CollectionUtils.isEmpty(dynformHeads) ? new ArrayList<>() : dynformHeads;

        boolean isDebugLog = log.isDebugEnabled();
        redisUtil.scan(DynformConstant.SYS_DYNFORM_CACHE_FIELDS_PREFIX.concat("*"), key -> {
            redisUtil.del(key);
            if (isDebugLog) {
                log.debug("dynform cache delete: key=[{}]", key);
            }
        });

        String tId, key, jsonStr;
        List<DynformFieldDTO> allFields;
        Gson gson = new GsonBuilder().serializeNulls().setDateFormat(DynformConstant.DATE_FMT_Y_M_D_H_M_S).create();
        for (DynformHead dynformHead : dynformHeads) {
            tId = dynformHead.getId();
            allFields = dynformAutoService.getTableAllField(tId);
            if (CollectionUtils.isEmpty(allFields)) {
                continue;
            }
            key = DynformConstant.SYS_DYNFORM_CACHE_FIELDS_PREFIX.concat(tId);
            jsonStr = gson.toJson(allFields);
            redisUtil.set(key, jsonStr);
            if (isDebugLog) {
                log.debug("set dynform cache: [key=[{}], val=[{}]]", key, jsonStr);
            }
        }
    }

    @Override
    public List<DynformFieldDTO> getItems(String tableId) {
        String tId = StringUtils.trimToEmpty(tableId);
        String key = DynformConstant.SYS_DYNFORM_CACHE_FIELDS_PREFIX.concat(tId);
        String fieldVoJson = redisUtil.getStr(key);

        // @formatter:off
        Type type = new TypeToken<List<DynformFieldDTO>>() {}.getType();
        // @formatter:on
        Gson gson = new GsonBuilder().serializeNulls().setDateFormat(DynformConstant.DATE_FMT_Y_M_D_H_M_S).create();

        List<DynformFieldDTO> fields = gson.fromJson(fieldVoJson, type);
        if (CollectionUtils.isNotEmpty(fields)) {
            return fields;
        }

        return new ArrayList<>();
    }
}
